package leetcode.p224;

import java.util.Stack;

/**
 * @author: trtan
 * @create: 2021-04-14 19:10
 * @description:
 **/
public class BasicCalculator {
    public static void main(String[] args) {
        String s = "(7)-(0)+(4)";
        System.out.println(new BasicCalculator().calculate(s));
    }

    Integer[][] relation = new Integer[200][200];

    void Init() {
        //#代表结束
        char[] symbols = new char[]{'+', '-', '*', '/', '(', ')', '#'};
        //priorities[i][j] 代表i符号在j符号前的优先级
        //1代表i优先级比j高
        //0代表i、j优先级相同
        //-1代表i优先级比j低
        //2代表这种情况不可能存在，如果出现了就是表达式有问题
        int[][] priorities = {
            {1, 1, -1, -1, -1, 1, 1},
            {1, 1, -1, -1, -1, 1, 1},
            {1, 1, 1, 1, -1, 1, 1},
            {1, 1, 1, 1, -1, 1, 1},
            {-1, -1, -1, -1, -1, 0, 2},
            {1, 1, 1, 1, 2, 1, 1},
            {-1, -1, -1, -1, -1, 2, 0},
        };
        for(int i = 0; i <= 6; i++) {
            for (int j = 0; j <= 6; j++) {
                relation[symbols[i]][symbols[j]] = priorities[i][j];
            }
        }
    }
    public int calculate(String s) {
        s = s.replaceAll(" ", "");
        StringBuilder newS = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (i == 0 && (ch > '9' || ch < '0')) {
                newS.append('0');
            }
            newS.append(ch);
            if (ch == '(' && (s.charAt(i + 1) > '9' || s.charAt(i + 1) < '0')) {
                newS.append('0');
            }
        }
        newS.append('#');
        s = newS.toString();
        System.out.println(s);
        Init();
        Stack<Integer> numbers = new Stack<>();
        Stack<Character> chars = new Stack<>();
        chars.push('#');
        int i = 0;
        while (i < s.length()) {
            int num = 0;
            boolean flag = false;
            char ch = s.charAt(i);
            if (ch >= '0' && ch <= '9') {
                flag = true;
                do {
                    num = num * 10 + ch - '0';
                    i++;
                    if (i < s.length()) {
                        ch = s.charAt(i);
                    }
                } while (i < s.length() && ch >= '0' && ch <= '9');
            }
            if (flag) {
                numbers.push(num);
            }
            char op = chars.peek();
            if (relation[op][ch] == -1) {
                chars.push(ch);
            } else if (relation[op][ch] == 1) {
                while (relation[op][ch] == 1) {
                    if (op == '#') {
                        break;
                    }
                    int num1 = 0, num2 = 0;
                    num2 = numbers.pop();
                    num1 = numbers.pop();
                    if (op == '+') {
                        numbers.push(num1 + num2);
                    } else if (op == '-') {
                        numbers.push(num1 - num2);
                    } else if (op == '*') {
                        numbers.push(num1 * num2);
                    } else if (op == '/') {
                        numbers.push(num1 / num2);
                    }
                    chars.pop();
                    op = chars.peek();
                }
                if (relation[op][ch] == -1) {
                    chars.push(ch);
                } else if (relation[op][ch] == 0) {
                    chars.pop();
                }
            } else if (relation[op][ch] == 0) {
                chars.pop();
            }
            i++;
        }
        return numbers.pop();
    }
}
